package com.zoe.onelink.logging.trace.property;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2021</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2021-08-05
 */
@Data
@ConfigurationProperties(prefix = "onelink.logging")
public class TraceLogProperties {

    /**
     * 请求日志配置
     */
    private HttpLogProperties http = new HttpLogProperties();

    /**
     * Feign日志配置
     */
    private FeignLogProperties feign = new FeignLogProperties();

    /**
     * Dubbo日志
     */
    private DubboLogProperties dubbo = new DubboLogProperties();

    /**
     * SQL日志配置
     */
    private SqlLogProperties sql = new SqlLogProperties();


    @Data
    public static class HttpLogProperties {

        /**
         * 启用
         */
        private boolean enabled = true;

        /**
         * 请求头文本最大长度 (超过此长度不记录对应的日志)
         */
        private int headerMaxLength = -1;

        /**
         * 请求参数最大长度 (超过此长度不记录对应的日志)
         */
        private int paramMaxLength = -1;

        /**
         * 请求返回结果最大长度(超过此长度不记录对应的日志)
         */
        private int resultMaxLength = 10240;

        /**
         * 当文本超过指定长度时的修剪方式: discard=丢弃 , sub=保留设定值的长度
         */
        private String trimType = "sub";

        /**
         * 仅允许特定的URL通过 , 如果配置了 onlyUrls , 那么 excludeUrls 将失效
         */
        private List<String> onlyUrls = new ArrayList<>();

        /**
         * 屏蔽特定的URL , 如果配置了 onlyUrls , 那么 excludeUrls 将失效
         */
        private List<String> excludeUrls = new ArrayList<>();

        /**
         * 要记录的请求头
         */
        private List<String> includeHeaders = new ArrayList<>();

        /**
         * 要排除的请求头
         */
        private List<String> excludeHeaders = new ArrayList<>();

    }

    @Data
    public static class FeignLogProperties {

        private boolean enabled = true;

        /**
         * 要记录的请求头
         */
        private List<String> includeHeaders = new ArrayList<>();

    }


    @Data
    public static class DubboLogProperties {

        /**
         * 启用
         */
        private boolean enabled = true;

        /**
         * 请求参数最大长度 (超过此长度不记录对应的日志)
         */
        private int paramMaxLength = -1;

        /**
         * 当文本超过指定长度时的修剪方式: discard=丢弃 , sub=保留设定值的长度
         */
        private String trimType = "sub";

        /**
         * 包含方法名 (例如: com.zoe.mapper.UserMapper.getById)
         * 注意: 如果配置了 includeMethods , 那么 excludeMethods 将失效
         */
        private List<String> includeMethods = new ArrayList<>();

        /**
         * 排除方法名 (例如: com.zoe.mapper.UserMapper.getById)
         * 注意: 如果配置了 includeMethods , 那么 excludeMethods 将失效
         */
        private List<String> excludeMethods = new ArrayList<>();
    }


    @Data
    public static class SqlLogProperties {

        /**
         * 启用
         */
        private boolean enabled = true;

        /**
         * SQL语法最大长度 (超过此长度自动裁剪至最大值)
         */
        private int grammarMaxLength = -1;

        /**
         * SQL参数体最大长度 (超过此长度自动裁剪至最大值)
         */
        private int paramMaxLength = -1;

        /**
         * 当文本超过指定长度时的截断策略: discard=丢弃 , sub=截取设定值的长度
         */
        private String trimType = "sub";

        /**
         * SQL语句策略 FILLED:填充参数后的SQL , PREPARED:编译SQL,语句与参数分开
         */
        private String strategy = Strategy.FILLED;

        /**
         * 包含方法名 (例如: com.zoe.mapper.UserMapper.getById)
         * 注意: 如果配置了 includeMethods , 那么 excludeMethods 将失效
         */
        private List<String> includeMethods = new ArrayList<>();

        /**
         * 排除方法名 (例如: com.zoe.mapper.UserMapper.getById)
         * 注意: 如果配置了 includeMethods , 那么 excludeMethods 将失效
         */
        private List<String> excludeMethods = new ArrayList<>();

        @Getter
        @AllArgsConstructor
        public static final class Strategy {

            /**
             * 填充参数后的SQL
             */
            public static final String FILLED = "FILLED";

            /**
             * 预编译SQL,语句与参数分开
             */
            public static final String PREPARED = "PREPARED";

            /**
             * 只记录预编译SQL,不记录参数
             */
            public static final String PREPARED_ONLY = "PREPARED_ONLY";

        }

    }

    /**
     * 当日志超过设定的最大长度时,执行的截断策略
     */
    @Getter
    @AllArgsConstructor
    public static final class TrimType {

        /**
         * 直接丢弃当前日志
         */
        public static final String DISCARD = "discard";

        /**
         * 截取设定值长度的日志
         */
        public static final String SUB = "sub";

    }


}
